#!/usr/bin/env bash

function usage {
    echo "usage:"
    echo "    ./scanner_test.sh [TEST_DATA_DIR]"
    echo "arguments:"
    echo "    TEST_DATA_DIR          where the test file is written, default to PREFIX"
}

function fail2die {
    "${@:2}"
    local status=$?
    if [ $status -ne 0 ]; then
        echo "failed: $@" >&2
        exit 1
    fi
}

TOTAL_CASES=0
SUCCESS_CASES=0
FAILURE_CASES=0
FAILURES_LINES=""
function ret_0 {
    ARGS=$@
    echo "test ret 0:" $@
    "${@:2}"
    if [ $? -ne 0 ]; then
        FAILURES_LINES=$(printf "${FAILURES_LINES}\nshould be 0: $ARGS")
        FAILURE_CASES=$(( FAILURE_CASES + 1 ))
    else
        SUCCESS_CASES=$(( SUCCESS_CASES + 1 ))
    fi
    TOTAL_CASES=$(( TOTAL_CASES + 1 ))
}

function ret_not_0 {
    ARGS=$@
    echo "test not ret 0:" $@
    "${@:2}"
    if [ $? -ne 0 ]; then
        SUCCESS_CASES=$(( SUCCESS_CASES + 1 ))
    else
        FAILURES_LINES=$(printf "${FAILURES_LINES}\nshould not be 0: $ARGS")
        FAILURE_CASES=$(( FAILURE_CASES + 1 ))
    fi
    TOTAL_CASES=$(( TOTAL_CASES + 1 ))
}
MY_DIR="$( cd "$( dirname "$0" )" && pwd )"
PREFIX="$( cd "$( dirname "$0" )/.." && pwd )"
echo "PREFIX is $PREFIX"
TEST_DATA_DIR="$PREFIX/test_bed"
if [[ -n "$1" ]]; then
    TEST_DATA_DIR=$( realpath $1 )
fi
export PREFIX="$PREFIX"
export DATA_DIR="$TEST_DATA_DIR"
. "$MY_DIR/config.sh"
SCANNER="$BIN_DIR/scanner.sh"
MERGE_SCANNER="$BIN_DIR/merge_scanner.sh"
# FFPROBE="$BIN_DIR/ffprobe"
FFPROBE="/usr/bin/ffprobe"
DATE="date"
TOUCH="touch"
if [[ "$(uname)" == "Darwin" ]]; then
    $(which gdate) &>/dev/null
    if [[ ! $? -eq 0 ]]; then
        echo "gdate not found, to install it with brew:"
        echo "    brew install coreutils"
        exit -1
    fi

    DATE="gdate"
    TOUCH="gtouch"
fi
# cases:
#   1. scanner
#       1.1 scanner optimistic path
#           1.1.1 trans-format should be triggered by endc.info
#           1.1.2 tlv files should be trans-formatted to recordings
#           1.1.3 the info file should be moved to recordings
#           1.1.4 tlv and its log should be moved to archives/success/
#           1.1.5 the dir contains tlv should be removed
#           1.1.6 the top dir tlvs/ should not be removed
#           1.1.7 * scanner should give a summary
#           1.1.8 tlv files in archives over 7 days should be removed
#           1.1.9 empty sub dir of tlvs/ should be removed
#           1.1.10 empty sub dir of archives/ should be removed
{

    fail2die $LINENO rm -rf "$TEST_DATA_DIR"
    fail2die $LINENO mkdir -p "$TEST_DATA_DIR"
    fail2die $LINENO mkdir -p "$INPUT_DIR/sample"
    fail2die $LINENO cp -f "$TEST_DIR/sample.tlv" "$INPUT_DIR/sample/sample.tlv"
    fail2die $LINENO ${SCANNER} --once
    ret_not_0 "1.1.1" "ls" "$OUTPUT_DIR/sample/sample.webm"
    fail2die $LINENO "$TOUCH" "$INPUT_DIR/sample/endc.info"
    fail2die $LINENO ${SCANNER} --once
    ret_0 "1.1.2" "$FFPROBE" -v quiet -hide_banner "$OUTPUT_DIR/sample/sample.webm"
    ret_0 "1.1.3" "ls" "$OUTPUT_DIR/sample/endc.info"
    ret_0 "1.1.4" ls "$HISTORY_DIR/success/sample/sample.tlv"
    ret_0 "1.1.4" ls "$HISTORY_DIR/success/sample/sample.tlv.log"
    ret_not_0 "1.1.5" "ls" "$INPUT_DIR/sample"
    fail2die $LINENO cp -f "$TEST_DIR/sample.tlv" "$INPUT_DIR/sample.tlv"
    fail2die $LINENO ${SCANNER} --once
    ret_0 "1.1.6" "ls" "$INPUT_DIR"

    # test cleanup
    fail2die $LINENO rm -rf "$TEST_DATA_DIR"
    fail2die $LINENO mkdir -p "$HISTORY_DIR/success/sample"
    fail2die $LINENO mkdir -p "$HISTORY_DIR/success/sample2"
    fail2die $LINENO cp -f "$TEST_DIR/sample.tlv" "$HISTORY_DIR/success/sample/sample.tlv"
    fail2die $LINENO cp -f "$TEST_DIR/sample.tlv" "$HISTORY_DIR/success/sample3.tlv"
    fail2die $LINENO "$TOUCH" -m -d "$( LANG=C "$DATE" -d "$( LANG=C "$DATE" ) -8 days" )" "$HISTORY_DIR/success/sample/sample.tlv"
    fail2die $LINENO "$TOUCH" -m -d "$( LANG=C "$DATE" -d "$( LANG=C "$DATE" ) -8 days" )" "$HISTORY_DIR/success/sample3.tlv"
    fail2die $LINENO ${SCANNER} --once
    ret_not_0 "1.1.8" "ls" "$HISTORY_DIR/success/sample/sample.tlv"
    ret_not_0 "1.1.8" "ls" "$HISTORY_DIR/success/sample3.tlv"
    ret_0 "1.1.8.2" ls "$HISTORY_DIR"
}
#       1.2 scanner pessimistic path
#           1.2.1 corrupted tlv should not be trans-formatted
#           1.2.2 currupted tlv and its log should be moved to archives/failure/
#           1.2.3 the info file should be moved to recordings/ even if any or all related tlv files are corrupted
#           1.2.4 the dir should be removed even if any or all related tlv files are corrupted
#           1.2.5 if a dir under tlvs/ was found without info file for over 24 hrs, it should be removed
#           1.2.5.1 the tlv files within in should be moved to /archives/no-info
#           1.2.5.2 the top dir should not be removed
#           1.2.6 empty dir under tlvs/ last modified over 1 day should be removed
#           1.2.7 empty dir under tlvs/ last modified within 1 day should not be removed
{
    fail2die $LINENO rm -rf "$TEST_DATA_DIR"
    fail2die $LINENO mkdir -p "$TEST_DATA_DIR"
    fail2die $LINENO mkdir -p "$INPUT_DIR/corrupted"
    fail2die $LINENO "$TOUCH" "$INPUT_DIR/corrupted/corrupted.tlv"
    fail2die $LINENO "$TOUCH" "$INPUT_DIR/corrupted/endc.info"
    fail2die $LINENO mkdir -p "$INPUT_DIR/timeout"
    fail2die $LINENO cp -f "$TEST_DIR/sample.tlv" "$INPUT_DIR/timeout/timeout.tlv"
    fail2die $LINENO cp -f "$TEST_DIR/sample.tlv" "$INPUT_DIR/timeout2.tlv"
    fail2die $LINENO mkdir -p "$INPUT_DIR/should_remove"
    fail2die $LINENO mkdir -p "$INPUT_DIR/should_not_remove"

    fail2die $LINENO "$TOUCH" -m -d "$( LANG=C "$DATE" -d "$( LANG=C "$DATE" ) -2 days" )" "$INPUT_DIR/timeout/timeout.tlv"
    fail2die $LINENO "$TOUCH" -m -d "$( LANG=C "$DATE" -d "$( LANG=C "$DATE" ) -2 days" )" "$INPUT_DIR/timeout"
    fail2die $LINENO "$TOUCH" -m -d "$( LANG=C "$DATE" -d "$( LANG=C "$DATE" ) -2 days" )" "$INPUT_DIR/timeout2.tlv"
    fail2die $LINENO "$TOUCH" -m -d "$( LANG=C "$DATE" -d "$( LANG=C "$DATE" ) -2 days" )" "$INPUT_DIR/should_remove"
    fail2die $LINENO "$SCANNER" --once
    ret_not_0 "1.2.1" ls "$OUTPUT_DIR/corrupted/corrupted.*"
    ret_0 "1.2.2" ls "$HISTORY_DIR/failure/corrupted/corrupted.tlv"
    ret_0 "1.2.2" ls "$HISTORY_DIR/failure/corrupted/corrupted.tlv.log"
    ret_0 "1.2.3" ls "$OUTPUT_DIR/corrupted/endc.info"
    ret_not_0 "1.2.4" ls "$INPUT_DIR/corrupted"
    # commented, it will be remove after 1 day, since when we remove files under it, it is modified
    #ret_not_0 "1.2.5" ls "$INPUT_DIR/timeout"
    ret_not_0 "1.2.5.1" ls "$INPUT_DIR/timeout/timeout.tlv"
    ret_not_0 "1.2.5.1" ls "$INPUT_DIR/timeout2.tlv"
    ret_0 "1.2.5.1" ls "$HISTORY_DIR/aged/timeout/timeout.tlv"
    ret_0 "1.2.5.1" ls "$HISTORY_DIR/aged/timeout2.tlv"
    ret_0 "1.2.5.2" ls "$INPUT_DIR"
    ret_not_0 "1.2.6" ls "$INPUT_DIR/should_remove"
    ret_0 "1.2.7" ls "$INPUT_DIR/should_not_remove"
}

#   3. transfmt cmd script
#       3.1 if DST_FORMAT is jpg, tlv should be converted to jpg
#       3.1.1 there should be a ts file
#       3.2 if DST_FORMAT is wav, tlv should be converted to wav
#       3.2.1 there should be a ts file
#       3.3 if DST_FORMAT not one of upper, tlv should be converted to mkv
#       3.3.1 there should be a ts file
#       3.4 original tlv should be moved to success if success
#       3.4.1 ts file should also be moved
#       3.4.2 ctx file should also be moved
#       3.5 original tlv should be moved to failure if failure
#       3.5.1 ts file should also be moved
#       3.5.2 ctx file should also be moved
#       3.6 transfmt file should be moved to success if success
#       3.7 transfmt file should be moved to failure if failure
#   todo implement 3.x test cases
{
    fail2die $LINENO rm -rf "$TEST_DATA_DIR"
    fail2die $LINENO mkdir -p "$TEST_DATA_DIR"
    fail2die $LINENO mkdir -p "$INPUT_DIR/test"
    fail2die $LINENO cp -f "$TEST_DIR/sample.tlv" "$INPUT_DIR/test/test1.tlv"
    fail2die $LINENO echo "SRC_FILE=test/test1.tlv" > "$INPUT_DIR/test/test1.transfmt"
    fail2die $LINENO echo "DST_FORMAT=\"jpg\"" >> "$INPUT_DIR/test/test1.transfmt"
    fail2die $LINENO touch "$INPUT_DIR/test/test1.ctx"
    fail2die $LINENO cp -f "$TEST_DIR/sample.tlv" "$INPUT_DIR/test/test2.tlv"
    fail2die $LINENO echo "SRC_FILE=test/test2.tlv" > "$INPUT_DIR/test/test2.transfmt"
    fail2die $LINENO echo "DST_FORMAT=\"wav\"" >> "$INPUT_DIR/test/test2.transfmt"
    fail2die $LINENO touch "$INPUT_DIR/test/test2.ctx"
    fail2die $LINENO cp -f "$TEST_DIR/sample.tlv" "$INPUT_DIR/test/test3.tlv"
    fail2die $LINENO echo "SRC_FILE=test/test3.tlv" > "$INPUT_DIR/test/test3.transfmt"
    fail2die $LINENO echo "DST_FORMAT=\"mkv\"" >> "$INPUT_DIR/test/test3.transfmt"
    fail2die $LINENO touch "$INPUT_DIR/test/test3.ctx"
    fail2die $LINENO echo "garbage" > "$INPUT_DIR/test/garbage.tlv"
    fail2die $LINENO echo "SRC_FILE=test/garbage.tlv" > "$INPUT_DIR/test/garbage.transfmt"
    fail2die $LINENO touch "$INPUT_DIR/test/garbage.ctx"
    fail2die $LINENO touch "$INPUT_DIR/test/empty.transfmt"
    fail2die $LINENO touch "$INPUT_DIR/test/test1.ctx"
    fail2die $LINENO "$SCANNER" --once
    ret_0 "3.1" ls "${RECORD_ON_DEMAND_DIR}/test/test1.jpg"
    ret_0 "3.1.1" ls "${RECORD_ON_DEMAND_DIR}/test/test1.ts"
    ret_0 "3.2" ls "${RECORD_ON_DEMAND_DIR}/test/test2.wav"
    ret_0 "3.2.1" ls "${RECORD_ON_DEMAND_DIR}/test/test2.ts"
    ret_0 "3.3" ls "${RECORD_ON_DEMAND_DIR}/test/test3.mkv"
    ret_0 "3.3.1" ls "${RECORD_ON_DEMAND_DIR}/test/test3.ts"
    ret_not_0 "3.4" ls "${INPUT_DIR}/test/test1.tlv.log"
    ret_0 "3.4" ls "${HISTORY_DIR}/success/test/test1.tlv"
    ret_0 "3.4" ls "${HISTORY_DIR}/success/test/test1.tlv.log"
    ret_0 "3.4.1" ls "${HISTORY_DIR}/success/test/test1.ts"
    ret_0 "3.4.2" ls "${HISTORY_DIR}/success/test/test1.ctx"
    ret_not_0 "3.4" ls "${INPUT_DIR}/test/test2.tlv.log"
    ret_0 "3.4" ls "${HISTORY_DIR}/success/test/test2.tlv"
    ret_0 "3.4" ls "${HISTORY_DIR}/success/test/test2.tlv.log"
    ret_0 "3.4.1" ls "${HISTORY_DIR}/success/test/test2.ts"
    ret_0 "3.4.2" ls "${HISTORY_DIR}/success/test/test2.ctx"
    ret_not_0 "3.4" ls "${INPUT_DIR}/test/test3.tlv.log"
    ret_0 "3.4" ls "${HISTORY_DIR}/success/test/test3.tlv"
    ret_0 "3.4" ls "${HISTORY_DIR}/success/test/test3.tlv.log"
    ret_0 "3.4.1" ls "${HISTORY_DIR}/success/test/test3.ts"
    ret_0 "3.4.2" ls "${HISTORY_DIR}/success/test/test3.ctx"
    ret_0 "3.5" ls "${HISTORY_DIR}/failure/test/garbage.tlv"
    #ret_0 "3.5.1" ls "${HISTORY_DIR}/failure/test/garbage.ts"
    ret_0 "3.5.2" ls "${HISTORY_DIR}/failure/test/garbage.ctx"
    ret_0 "3.6" ls "${HISTORY_DIR}/success/test/test1.transfmt"
    ret_0 "3.6" ls "${HISTORY_DIR}/success/test/test2.transfmt"
    ret_0 "3.6" ls "${HISTORY_DIR}/success/test/test3.transfmt"
    ret_0 "3.7" ls "${HISTORY_DIR}/failure/test/garbage.transfmt"
    ret_0 "3.7" ls "${HISTORY_DIR}/failure/test/empty.transfmt"
}
# 4 merge scanner
#   4.1 once a merge.this.directory file found in merge-in dir or its sub-dirs, media files under same dir will be merged
#       4.1.1 merge.this.directory file should be removed
#   4.2 if merge success,
#       4.2.1 input media file should be moved to archives/merge-success/
#       4.2.2 ts file should be moved to archives/merge-success/
#   4.3 if merge failure,
#       4.3.1 input media file should be moved to archives/merge-failure/
#       4.3.2 ts file should be moved to archives/merge-failure
#   4.4 file under MERGE_IN_DIR not modified in last 7 days should be removed
#   4.5 empty dir under MERGE_IN_DIR not modified in last 1 day should be removed
#   4.6 file under MERGE_OUT_DIR not modified in last 7 days should be removed
#   4.7 empty dir under MERGE_OUT_DIR not modified in last 1 day should be removed
{
    fail2die $LINENO rm -rf "$TEST_DATA_DIR"
    fail2die $LINENO mkdir -p "$TEST_DATA_DIR"
    fail2die $LINENO mkdir -p "$MERGE_IN_DIR/"
    # prepare the merge-test
    fail2die $LINENO mkdir -p "$MERGE_IN_DIR/merge-test/"
    fail2die $LINENO cp -f "$TEST_DIR/sample.tlv" "$MERGE_IN_DIR/merge-test/1.tlv"
    fail2die $LINENO "$BIN_DIR/transfmt" "$MERGE_IN_DIR/merge-test/1.tlv" "$MERGE_IN_DIR/merge-test"
    # sample.tlv is vp8 encoded, so the output should be webm
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.webm" "$MERGE_IN_DIR/merge-test/2.webm"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.webm" "$MERGE_IN_DIR/merge-test/3.webm"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.webm" "$MERGE_IN_DIR/merge-test/4.webm"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.webm" "$MERGE_IN_DIR/merge-test/5.webm"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.webm" "$MERGE_IN_DIR/merge-test/6.webm"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.webm" "$MERGE_IN_DIR/merge-test/7.webm"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.webm" "$MERGE_IN_DIR/merge-test/8.webm"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.webm" "$MERGE_IN_DIR/merge-test/9.webm"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.ts" "$MERGE_IN_DIR/merge-test/2.ts"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.ts" "$MERGE_IN_DIR/merge-test/3.ts"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.ts" "$MERGE_IN_DIR/merge-test/4.ts"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.ts" "$MERGE_IN_DIR/merge-test/5.ts"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.ts" "$MERGE_IN_DIR/merge-test/6.ts"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.ts" "$MERGE_IN_DIR/merge-test/7.ts"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.ts" "$MERGE_IN_DIR/merge-test/8.ts"
    fail2die $LINENO cp -f "$MERGE_IN_DIR/merge-test/1.ts" "$MERGE_IN_DIR/merge-test/9.ts"
    fail2die $LINENO rm -f "$MERGE_IN_DIR/merge-test/1.tlv"
    fail2die $LINENO touch "$MERGE_IN_DIR/merge-test/merge.this.directory"
    # prepare the merge-test-missing-ts
    fail2die $LINENO cp -Rf "$MERGE_IN_DIR/merge-test" "$MERGE_IN_DIR/merge-test-missing-ts"
    fail2die $LINENO rm -f "$MERGE_IN_DIR/merge-test-missing-ts/6.ts"
    # prepare the merge-test-cleanup
    fail2die $LINENO mkdir -p "$MERGE_IN_DIR/merge-test-cleanup"
    fail2die $LINENO "$TOUCH" -m -d "$( LANG=C "$DATE" -d "$( LANG=C "$DATE" ) -8 days" )" "$MERGE_IN_DIR/merge-test-cleanup/some.file.modified.8.days.ago"
    fail2die $LINENO mkdir -p "$MERGE_IN_DIR/merge-test-cleanup/some.dir.modified.2.days.ago"
    fail2die $LINENO "$TOUCH" -m -d "$( LANG=C "$DATE" -d "$( LANG=C "$DATE" ) -2 days" )" "$MERGE_IN_DIR/merge-test-cleanup/some.dir.modified.2.days.ago"
    fail2die $LINENO mkdir -p "$MERGE_OUT_DIR/merge-test-cleanup"
    fail2die $LINENO "$TOUCH" -m -d "$( LANG=C "$DATE" -d "$( LANG=C "$DATE" ) -8 days" )" "$MERGE_OUT_DIR/merge-test-cleanup/some.file.modified.8.days.ago"
    fail2die $LINENO mkdir -p "$MERGE_OUT_DIR/merge-test-cleanup/some.dir.modified.2.days.ago"
    fail2die $LINENO "$TOUCH" -m -d "$( LANG=C "$DATE" -d "$( LANG=C "$DATE" ) -2 days" )" "$MERGE_OUT_DIR/merge-test-cleanup/some.dir.modified.2.days.ago"
    fail2die $LINENO "$MERGE_SCANNER" --once

    # tests
    ret_0 "4.1" ls "$MERGE_OUT_DIR/merge-test/merge-test.mp4"
    ret_not_0 "4.1.1" ls "$MERGE_IN_DIR/merge-test/merge.this.directory"
    ret_0 "4.2.1" ls "$HISTORY_DIR/merge-success/merge-test/1.webm"
    ret_0 "4.2.1" ls "$HISTORY_DIR/merge-success/merge-test/2.webm"
    ret_0 "4.2.1" ls "$HISTORY_DIR/merge-success/merge-test/3.webm"
    ret_0 "4.2.1" ls "$HISTORY_DIR/merge-success/merge-test/4.webm"
    ret_0 "4.2.1" ls "$HISTORY_DIR/merge-success/merge-test/5.webm"
    ret_0 "4.2.1" ls "$HISTORY_DIR/merge-success/merge-test/6.webm"
    ret_0 "4.2.1" ls "$HISTORY_DIR/merge-success/merge-test/7.webm"
    ret_0 "4.2.1" ls "$HISTORY_DIR/merge-success/merge-test/8.webm"
    ret_0 "4.2.1" ls "$HISTORY_DIR/merge-success/merge-test/9.webm"
    ret_0 "4.2.2" ls "$HISTORY_DIR/merge-success/merge-test/1.ts"
    ret_0 "4.2.2" ls "$HISTORY_DIR/merge-success/merge-test/2.ts"
    ret_0 "4.2.2" ls "$HISTORY_DIR/merge-success/merge-test/3.ts"
    ret_0 "4.2.2" ls "$HISTORY_DIR/merge-success/merge-test/4.ts"
    ret_0 "4.2.2" ls "$HISTORY_DIR/merge-success/merge-test/5.ts"
    ret_0 "4.2.2" ls "$HISTORY_DIR/merge-success/merge-test/6.ts"
    ret_0 "4.2.2" ls "$HISTORY_DIR/merge-success/merge-test/7.ts"
    ret_0 "4.2.2" ls "$HISTORY_DIR/merge-success/merge-test/8.ts"
    ret_0 "4.2.2" ls "$HISTORY_DIR/merge-success/merge-test/9.ts"

    ret_0 "4.3.1" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/1.webm"
    ret_0 "4.3.1" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/2.webm"
    ret_0 "4.3.1" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/3.webm"
    ret_0 "4.3.1" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/4.webm"
    ret_0 "4.3.1" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/5.webm"
    ret_0 "4.3.1" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/6.webm"
    ret_0 "4.3.1" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/7.webm"
    ret_0 "4.3.1" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/8.webm"
    ret_0 "4.3.1" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/9.webm"
    ret_0 "4.3.2" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/1.ts"
    ret_0 "4.3.2" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/2.ts"
    ret_0 "4.3.2" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/3.ts"
    ret_0 "4.3.2" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/4.ts"
    ret_0 "4.3.2" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/5.ts"
    # 6.ts is missing
    ret_0 "4.3.2" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/7.ts"
    ret_0 "4.3.2" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/8.ts"
    ret_0 "4.3.2" ls "$HISTORY_DIR/merge-failure/merge-test-missing-ts/9.ts"

    ret_not_0 "4.4" ls "$MERGE_IN_DIR/merge-test-cleanup/some.file.modified.8.days.ago"
    ret_not_0 "4.5" ls "$MERGE_IN_DIR/merge-test-cleanup/some.dir.modified.2.days.ago"
    ret_not_0 "4.4" ls "$MERGE_OUT_DIR/merge-test-cleanup/some.file.modified.8.days.ago"
    ret_not_0 "4.5" ls "$MERGE_OUT_DIR/merge-test-cleanup/some.dir.modified.2.days.ago"
}
# report
{
    echo "==========================================================="
    echo "summary:"
    echo "    $SUCCESS_CASES successful, $FAILURE_CASES failed, out of total $TOTAL_CASES cases"
    if [[ $FAILURE_CASES > 0 ]]; then
        echo "failures:"
        for line in "$FAILURES_LINES"; do
            echo "    $line"
        done
    fi
    echo "==========================================================="
}
